package com.ds.infrastructure.hyperspace.console.controller;

import com.ds.infrastructure.hyperspace.console.common.methodlock.MethodLockId;
import com.ds.infrastructure.hyperspace.console.config.shiro.ShiroToken;
import com.ds.infrastructure.hyperspace.console.entity.enums.TbContainerConfigEnum;
import com.ds.infrastructure.hyperspace.console.entity.enums.TbPublicEnum;
import com.ds.infrastructure.hyperspace.console.entity.page.TbPageWhere;
import com.ds.infrastructure.hyperspace.console.entity.table.TbContainerConfig;
import com.ds.infrastructure.hyperspace.console.entity.table.TbReleaseTask;
import com.ds.infrastructure.hyperspace.console.entity.table.TbStage;
import com.ds.infrastructure.hyperspace.console.entity.where.TbEnvironmentCustomWhere;
import com.ds.infrastructure.hyperspace.console.entity.where.TbReleaseTaskCustomWhere;
import com.ds.infrastructure.hyperspace.console.exceptions.HyperspaceException;
import com.ds.infrastructure.hyperspace.console.model.request.container.*;
import com.ds.infrastructure.hyperspace.console.model.request.form.PageForm;
import com.ds.infrastructure.hyperspace.console.model.response.container.GetReleaseTaskListVO;
import com.ds.infrastructure.hyperspace.console.model.response.container.ListContainerVO;
import com.ds.infrastructure.hyperspace.console.model.response.result.JsonResult;
import com.ds.infrastructure.hyperspace.console.model.response.result.JsonResultData;
import com.ds.infrastructure.hyperspace.console.model.response.result.JsonResultList;
import com.ds.infrastructure.hyperspace.console.model.response.result.JsonResultOk;
import com.ds.infrastructure.hyperspace.console.service.inf.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author: yaozhendong
 * @create: 2019-10-16 10:40
 **/
@RestController
@RequestMapping(value = "/container", produces = {"application/json;charset=UTF-8"})
@Api(value = "Manager Container Controller", tags = "网关管理")
public class ContainerController {
    @Autowired
    IStageService iStageService;
    @Autowired
    IContainerConfigService iContainerConfigService;
    @Autowired
    IContainerManageService iContainerManageService;
    @Autowired
    IReleaseTaskService iReleaseTaskService;
    @Autowired
    ISSOService iSSOService;

    @GetMapping(value = "/get")
    @ApiOperation(value = "查看-通过stageId网关配置数据")
    public JsonResultData<SaveContainerForm> get(@RequestParam(name = "stageId") Long stageId) {
        TbStage tbStageEntity = iStageService.getOrThrow(stageId);
        TbContainerConfig entity = iContainerConfigService.selectLastOne(tbStageEntity.getId(), tbStageEntity.getEnvironmentId());
        if (entity == null) {
            entity = iContainerConfigService.getLastOneWithMethodLockId(MethodLockId.newId(stageId), tbStageEntity.getId(), tbStageEntity.getEnvironmentId());
        }
        SaveContainerForm result = SaveContainerForm.toVO(entity);
        return JsonResultData.build(result);
    }

    @GetMapping(value = "/getById")
    @ApiOperation(value = "查看-通过id网关配置数据")
    public JsonResultData<SaveContainerForm> getById(@RequestParam(name = "id") Long id) {
        TbContainerConfig entity = iContainerConfigService.get(id);
        if (entity == null) {
            throw new HyperspaceException("获取网关配置数据失败，没有找到对应的记录，id=" + id);
        }
        SaveContainerForm result = SaveContainerForm.toVO(entity);
        return JsonResultData.build(result);
    }

    @PostMapping(value = "/save")
    @ApiOperation(value = "保存-网关配置数据")
    public JsonResult save(@RequestBody @Valid SaveContainerForm form) {
        TbContainerConfig oldEntity = iContainerConfigService.get(form.getId());
        if (oldEntity == null) {
            throw new HyperspaceException("保存网关配置数据失败，没有找到对应的记录，id=" + form.getId());
        }
        if (TbContainerConfigEnum.EDIT_STATE.NO.code.equals(oldEntity.getEditState())) {
            throw new HyperspaceException("当前记录已被激活，不可编辑");
        }
        //
        TbContainerConfig newEntity = SaveContainerForm.toEntity(form);
        iContainerConfigService.updateWithTimestamp(newEntity);
        return JsonResultOk.SUCCESS;
    }

    @PostMapping(value = "/commit")
    @ApiOperation(value = "提交网关配置")
    public JsonResult commit(@RequestBody @Valid CommitContainerForm form) {
        TbContainerConfig entity = iContainerConfigService.getOrThrow(form.getId(), "提交网关配置数据失败");
        if (TbContainerConfigEnum.EDIT_STATE.NO.code.equals(entity.getEditState())) {
            throw new HyperspaceException("当前记录已被提交，不要重复提交！");
        }
        if (entity.getGmtModified().compareTo(form.getGmtModified()) != 0) {
            throw new HyperspaceException("当前记录提交失败，数据时间戳不一致。当前记录已被修改");
        }
        SaveContainerForm.checkConfigData(entity);
        entity.setDescription(form.getDescription());
        ShiroToken.User currentUser = iSSOService.getCurrentUser();
        iContainerConfigService.commit(MethodLockId.newId(entity.getStageId()), entity, currentUser.getName(), currentUser.getId());
        return JsonResultOk.SUCCESS;
    }

    @ApiIgnore
    @GetMapping(value = "/rollback")
    @ApiOperation(value = "回滚-通过id网关配置数据")
    public JsonResult rollback(@RequestParam(name = "id") Long id) {
        if (System.currentTimeMillis() > 0) {
            throw new HyperspaceException("此接口暂时停用。");
        }
        TbContainerConfig entity = iContainerConfigService.get(id);
        if (entity == null) {
            throw new HyperspaceException("回滚网关配置数据失败，没有找到对应的记录，id=" + id);
        }
        if (!TbContainerConfigEnum.EDIT_STATE.NO.code.equals(entity.getEditState())) {
            throw new HyperspaceException("当前记录没有被提交，不能回滚，id=" + id);
        }
        int count = iContainerConfigService.rollback(entity);
        if (count == 0) {
            throw new HyperspaceException("回滚失败，count=0");
        }
        return JsonResultOk.SUCCESS;
    }

    @PostMapping(value = "/list")
    @ApiOperation(value = "列表-网关配置")
    public JsonResultList<ListContainerVO> list(@RequestBody @Valid ListContainerForm form) {
        TbContainerConfig where = ListContainerForm.toEntity(form);
        TbPageWhere pageWhere = PageForm.toPageWhere(form);
        int dataTotal = iContainerConfigService.getTotal(where, null);
        if (dataTotal == 0 || pageWhere.getBegin() > dataTotal) {
            return JsonResultList.build(Collections.emptyList(), dataTotal);
        }
        List<TbContainerConfig> tbContainerList = iContainerConfigService.getList(where, new TbEnvironmentCustomWhere().setOrderByType(TbPublicEnum.ORDER_BY_TYPE.ID_DESC.value), pageWhere);
        List<ListContainerVO> dataList = new ArrayList<>();
        tbContainerList.forEach(item -> dataList.add(ListContainerVO.toVO(item)));
        return JsonResultList.build(dataList, dataTotal);
    }

    @PostMapping(value = "/apply")
    @ApiOperation(value = "应用网关配置")
    public JsonResultData<Long> apply(@RequestBody @Valid ApplyContainerForm form) {
        TbContainerConfig entity = iContainerConfigService.get(form.getContainerConfigId());
        SaveContainerForm.checkConfigData(entity);
        Long taskId = iContainerManageService.release(form.getContainerConfigId(), form.getDeployTaskId(), form.getHostGroupIds());
        iContainerManageService.executeReleaseTask(taskId);
        return JsonResultData.build(taskId);
    }


    @PostMapping(value = "/getReleaseTaskList")
    @ApiOperation(value = "列表-配置发布任务列表")
    public JsonResultList<GetReleaseTaskListVO> getReleaseTaskList(@RequestBody @Valid GetReleaseTaskListForm form) {
        iStageService.getOrThrow(form.getStageId());
        TbReleaseTask where = GetReleaseTaskListForm.toEntity(form);
        TbReleaseTaskCustomWhere customWhere = new TbReleaseTaskCustomWhere().setOrderByType(TbPublicEnum.ORDER_BY_TYPE.ID_DESC.value);
        TbPageWhere pageWhere = PageForm.toPageWhere(form);
        List<TbReleaseTask> tbReleaseTaskList = iReleaseTaskService.getList(where, customWhere, pageWhere);
        List<GetReleaseTaskListVO> dataList = new ArrayList<>();
        tbReleaseTaskList.forEach(item -> dataList.add(GetReleaseTaskListVO.toVO(item)));
        return JsonResultList.build(dataList);
    }
}
